package net.Stratus.ImageDumper.GUI;

import java.util.ArrayList;
import java.util.Random;

import net.Stratus.ImageDumper.Job;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Table;
import org.eclipse.jface.viewers.TableViewer;

import com.ibm.icu.text.DecimalFormat;

public class ManageJobs {

	private static ArrayList<ManageJobs> instances = new ArrayList<ManageJobs>();
	protected Shell shell;
	private Table table;
	private ArrayList<ProgressBar> barz;
	private boolean markedForUpdate = false;
	
	/**
	 * Creates a new MangageJobs Window
	 */
	public static void create() {
		try {
			ManageJobs window = new ManageJobs();
			window.open();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Checks if there are open windows left
	 * @return if there are open windows left
	 */
	public static boolean hasWindows() {
		return (instances.size() > 0);
	}
	
	
	/**
	 * Open the window.
	 * 
	 * @wbp.parser.entryPoint
	 */
	public void open() {
		Display display = Display.getDefault();
		createContents();
		shell.open();
		shell.layout();
		instances.add(this);
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		instances.remove(this);
	}

	/**
	 * Create contents of the window.
	 */
	protected void createContents() {
		barz = new ArrayList<ProgressBar>();
		shell = new Shell();
		shell.setSize(450, 300);
		shell.setText("Image Dumper - Add Job");
		shell.setLayout(new FillLayout(SWT.HORIZONTAL));

		Menu menu = new Menu(shell, SWT.BAR);
		shell.setMenuBar(menu);

		MenuItem mntmNewJob = new MenuItem(menu, SWT.NONE);
		mntmNewJob.setText("New Job");
		mntmNewJob.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				AddJob.create();
			}
		});

		MenuItem mntmAbout = new MenuItem(menu, SWT.NONE);
		mntmAbout.setText("About");
		mntmAbout.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				ManageJobs.create();
			}
		});

		TableViewer tableViewer = new TableViewer(shell, SWT.BORDER | SWT.FULL_SELECTION);
		// get and config table
		table = tableViewer.getTable();
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		// add & name columns
		new TableColumn(table, SWT.NONE).setText("Job ID");
		new TableColumn(table, SWT.NONE).setText("Type");
		new TableColumn(table, SWT.NONE).setText("KB Downloaded");
		new TableColumn(table, SWT.NONE).setText("Progress");
		new TableColumn(table, SWT.NONE).setText("Progress");				
		updateData();		
		// resize columns
		table.getColumn(0).pack();
		table.getColumn(1).pack();
		table.getColumn(2).pack();
		table.getColumn(3).pack();
		table.getColumn(4).setWidth(128);
		table.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				// don't know any better way to do this
				for(int i = 0; i < table.getItemCount(); i++) {
					if(e.item.equals(table.getItem(i))) {
						JobViewer.create(Job.getJobs().get(i).getID());
					}
				}
			}
		});
	}

	/**
	 * Calls updateDate asynchronously on all windows
	 */
	public static void updateDataAll() {
		// loop through all instances and update them
		for (int i = 0; i < instances.size(); i++) {
			// by calling updateDate asynchronously
			final ManageJobs mj = instances.get(i);
			Display.getDefault().syncExec(new Runnable() {
				public void run() {
					mj.updateData();
		        }
			});
		}
	}
	
	/**
	 * Update rows in table
	 */
	public void updateData() {
		if(table.isDisposed()) {
			instances.remove(this);
			return;
		}		

		ArrayList<Job> jobs = Job.getJobs();
		DecimalFormat dmt = new DecimalFormat("0.00"); // DMT anyone?
				
		if(markedForUpdate || table.getItemCount() != jobs.size()) {
			markedForUpdate = false;
			table.removeAll();
			// clean progress bars
			for(int i = 0; i < barz.size(); i++) {
				barz.get(i).dispose();
			}
			barz.clear();
			for (int i = 0; i < jobs.size(); i++) {
				Job job = jobs.get(i);
				TableItem item = new TableItem(table, SWT.NONE);			
				// set up text in row
				String[] rowText = new String[4];
				rowText[0] = job.getID()+"";
				rowText[1] = job.getIdenftifier();
				rowText[2] = (job.getKBLimit() == 0) ? job.getKBDownloaded()+"" : job.getKBDownloaded()+"/"+job.getKBLimit();
				rowText[3] = (!job.canCount() ||  job.getTotal() == -1) ? job.getDownloaded()+"/?" :  job.getDownloaded()+"/"+job.getTotal();
				item.setText(rowText);
				// put progress bar in
				TableEditor editor = new TableEditor(table);
				editor.grabHorizontal = editor.grabVertical = true;
				ProgressBar bar = new ProgressBar(table, (!job.canCount() ||  job.getTotal() == -1) ? SWT.INDETERMINATE: SWT.NONE);
				bar.setSelection(job.getDownloaded());
				bar.setMaximum(job.getTotal());
				editor.setEditor(bar, item, 4);
				barz.add(bar); // add to barz
			}
		} else {
			for(int i = 0; i < table.getItemCount(); i++) {
				TableItem item = table.getItem(i);
				Job job = jobs.get(i);
				// set text
				String[] rowText = new String[4];
				rowText[0] = job.getID()+"";
				rowText[1] = job.getIdenftifier();
				rowText[2] = (job.getKBLimit() == 0) ? job.getKBDownloaded()+"" : job.getKBDownloaded()+"/"+job.getKBLimit();
				rowText[3] = (!job.canCount() ||  job.getTotal() == -1) ? job.getDownloaded()+"/?" :  job.getDownloaded()+"/"+job.getTotal();
				item.setText(rowText);
				// update progressbar
				ProgressBar bar = barz.get(i);
					// switch from indeterminate to normal?
				if((bar.getStyle() & SWT.INDETERMINATE) == SWT.INDETERMINATE &&  job.canCount() && job.getTotal() != -1) {
					markedForUpdate = true;
					/**
					 * We have found a progressbar that has the SWT.INDETERMINATE
					 * style flag and should no longer have it. With SWT the only
					 * way to change the style flag is to create a new progress bar.
					 * So we set markedForUpdate to true so that the entire table
					 * can be redone on the next update. The progress bar will also
					 * no longer have the SWT.INDETERMINATE style flag.
					 */
				}				
				bar.setSelection(job.getDownloaded());				
			}
		}
	}
}
